import React, { useRef, useState, useEffect } from 'react';
import { ProTable, ActionType, ProColumns } from '@ant-design/pro-components';
import { message, Button, Popconfirm, Table, Space, Modal } from 'antd';
import { ExceptionOutlined, EyeOutlined } from '@ant-design/icons';
import { downloadFile, proTableRequest, saveDataParams } from '@/app/common/utils';

import ImportTableForm from './ImportTableForm';
import PreViewContent from './PreViewContent';
import EditTableCol from './EditTableCol';

export type GenType = {
  tableId: number;
  tableName: string;
  tableComment: string;
  subTableName: string;
  subTableFkName: string;
  className: string;
  tplCategory: string;
  packageName: string;
  moduleName: string;
  businessName: string;
  functionName: string;
  functionAuthor: string;
  genType: string;
  genPath: string;
  pkColumn: string;
  subTable: string;
  columns: string[];
};

// 代码生成页面
export default function Gen() {
  const actionRef = useRef<ActionType>();
  // 选中的表key
  const [tableKeys, setTableKeys] = useState<React.Key[]>([]);
  // 代码预览弹窗是否展示
  const [isPreview, setPreivew] = useState<boolean>();
  // 字典类型下拉框数据
  const [optionselect, setOptionselect] = useState<Record<string, any>[]>();
  // 菜单下拉树列表
  const [tree, setTree] = useState<Record<string, any>[]>();
  // 代码预览数据
  const [code, setCode] = useState<object>({});

  // 获取字典类型下拉框
  useEffect(() => {
    $get('/system/dict/type/optionselect').then(res => {
      if (res.code === 200) {
        setOptionselect(res.data);
      }
    });
    $get('/system/menu/treeselect').then(res => {
      if (res.code === 200) {
        setTree(res.data);
      }
    });
  }, []);

  // 表格列属性
  const columns: ProColumns<GenType>[] = [
    {
      title: 'id',
      dataIndex: 'tableId',
      search: false,
      editable: false,
    },
    {
      title: '表名',
      dataIndex: 'tableName',
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项',
          },
        ],
      },
    },
    {
      title: '表描述',
      dataIndex: 'tableComment',
      valueType: 'text',
    },
    {
      title: '实体类名',
      dataIndex: 'className',
      valueType: 'text',
    },
    {
      title: '创建时间',
      key: 'createTime',
      dataIndex: 'createTime',
      valueType: 'dateTime',
      sorter: true,
      hideInSearch: true,
      editable: false,
    },
    {
      title: '更新时间',
      key: 'updateTime',
      dataIndex: 'updateTime',
      valueType: 'dateTime',
      sorter: true,
      hideInSearch: true,
      editable: false,
    },
    {
      title: '操作',
      valueType: 'option',
      key: 'option',
      render: (_text, record, _, action) => {
        return [
          <a
            key="preview"
            onClick={async () => {
              const res = await $get(`/tool/gen/preview/${record.tableId}`);
              setPreivew(true);
              setCode(res.data);
            }}
          >
            <Space>
              <EyeOutlined />
              预览
            </Space>
          </a>,
          <EditTableCol
            key="EditTableCol"
            record={record}
            optionselect={optionselect}
            tree={tree}
          />,
          <Popconfirm
            key="del-gen"
            title={`确定要删除【${record.tableName}】的代码生成？`}
            onConfirm={async () => {
              const res = await $delete(`/tool/gen/${record.tableId}`);
              if (res.code === 200) {
                message.success(`删除 ${record.tableName}的表生成数据成功`);
              }
              action.reload();
            }}
          >
            <a key="del">删除</a>
          </Popconfirm>,
        ];
      },
    },
  ];

  // 删除表的代码生成数据
  const delTableGen = async (tableKeys: React.Key[] = []) => {
    const res = await $delete(`/tool/gen/${tableKeys}`);
    if (res.code === 200) {
      message.success(`删除 [${tableKeys.join(',')}]的表生成数据成功`);
    }
    actionRef.current.reload();
    actionRef.current.clearSelected();
  };

  // 预览代码关闭并清空
  const closePreView = () => {
    setCode({});
    setPreivew(false);
  };

  return (
    <>
      <ProTable<GenType>
        columns={columns}
        actionRef={actionRef}
        request={proTableRequest('/tool/gen/list')}
        editable={{
          type: 'multiple',
          onSave: async function(_key, record) {
            const res = await $put('/tool/gen', { ...saveDataParams(record) });
            if (res.code === 200) {
              message.success('修改成功');
            }
            actionRef.current.reload();
          },
          onDelete: async function(_key) {
            const res = await $delete(`/tool/gen/${_key}`);
            if (res.code === 200) {
              message.success('删除成功');
            }
          },
        }}
        rowKey="tableId"
        search={{
          labelWidth: 'auto',
        }}
        options={{
          setting: {
            listsHeight: 800,
          },
        }}
        pagination={{
          pageSize: 10,
        }}
        dateFormatter="string"
        headerTitle="系统参数"
        toolBarRender={action => [
          <ImportTableForm actionRef={action} />,
          <Button
            type="primary"
            icon={<ExceptionOutlined />}
            onClick={async () => {
              const isSuccess = await downloadFile('/tool/gen/export');
              if (isSuccess) {
                message.success('下载成功');
              }
            }}
          >
            导出列表
          </Button>,
          <Popconfirm
            onConfirm={() => delTableGen(tableKeys)}
            title={`确定要删除 【${tableKeys.join(', ')}】 这几个表的代码生成？`}
          >
            <Button type="primary" disabled={tableKeys.length < 1} danger>
              删除
            </Button>
          </Popconfirm>,
        ]}
        rowSelection={{
          selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
          onChange(selectedRowKeys, _selectedRows, _info) {
            setTableKeys(selectedRowKeys);
          },
        }}
      />
      <Modal
        title="代码预览"
        width={1000}
        visible={isPreview}
        onCancel={closePreView}
        onOk={closePreView}
      >
        <PreViewContent codeObj={code} />
      </Modal>
    </>
  );
}
